home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 351-375 / 351 / pdc / pdcsrc.lzh / PDC / GenCode.c < prev    next >
C/C++ Source or Header  |  1990-04-06  |  63KB  |  2,525 lines

  1.  
  2. /* PDC Compiler - A Freely Distributable C Compiler for the Amiga
  3.  *                Based upon prior work by Matthew Brandt and Jeff Lydiatt.
  4.  *
  5.  * PDC Compiler release 3.3 Copyright (C) 1989 Paul Petersen and Lionel Hummel.
  6.  * PDC Software Distribution (C) 1989 Lionel Hummel and Paul Petersen.
  7.  *
  8.  * This code is freely redistributable upon the conditions that this 
  9.  * notice remains intact and that modified versions of this file not be 
  10.  * distributed as part of the PDC Software Distribution without the express
  11.  * consent of the copyright holders.
  12.  *
  13.  *------------------------------------------------------------------
  14.  *
  15.  * $Log:    GenCode.c,v $
  16.  * Revision 3.33  90/04/05  22:30:42  lionel
  17.  * Changed library function callout to avoid collisions with user functions.
  18.  * Added generation of unsigned *, /, and % expressions.
  19.  * 
  20.  * Revision 3.32  90/02/03  16:23:57  lionel
  21.  * None
  22.  * 
  23.  *------------------------------------------------------------------
  24.  */
  25.  
  26. /*
  27.  * GenCode.c
  28.  * 
  29.  * This module contains all of the code generation routines for evaluating
  30.  * expressions and conditions.
  31.  */
  32.  
  33. #include    <stdio.h>
  34. #include    "C.h"
  35. #include    "Expr.h"
  36. #include    "Gen.h"
  37. #include    "Cglbdec.h"
  38.  
  39. extern char    *xalloc();
  40. extern TYP      stdint;
  41.  
  42. #define MAX_SHIFT   8
  43.  
  44. SYM            *gsearch();
  45.  
  46. struct amode   *temp_data(), *temp_addr(), *makeareg(), *makedreg();
  47. struct amode   *copy_addr(), *temp_float();
  48. struct amode   *request_addr(), *request_data(), *request_float();
  49. struct amode   *request_reg();
  50. struct enode   *makenode();
  51.  
  52. struct amode   *gen_fsconvert(), *gen_fconvert();
  53. struct amode   *gen_fsbinary(), *gen_fbinary();
  54. struct amode   *gen_fsunary(), *gen_funary();
  55. struct amode   *gen_fsaincdec(), *gen_faincdec();
  56.  
  57. struct amode   *gen_stabn(), *gen_stabs();
  58.  
  59. extern long floatlit();
  60. extern struct amode push[], pop[];
  61.  
  62. struct amode   *gen_expr();                          /* forward declaration */
  63. void            swap_nodes(), truejp(), falsejp();   /* ditto               */
  64.  
  65. int
  66. istemp(ap)
  67.     struct amode   *ap;
  68. {
  69.     if (ap->mode == am_areg && (int) ap->preg <= 1)
  70.         return TRUE;
  71.     else if (ap->mode == am_dreg && (int) ap->preg <= 2)
  72.         return TRUE;
  73.     return FALSE;
  74. }
  75.  
  76. struct amode   *
  77. make_label(lab)
  78.  
  79. /*
  80.  * construct a reference node for an internal label number.
  81.  */
  82.     int             lab;
  83. {
  84.     struct enode   *lnode;
  85.     struct amode   *ap;
  86.  
  87.     lnode = (struct enode *) xalloc(sizeof(struct enode));
  88.     lnode->signedflag = 0;
  89.     lnode->nodetype = en_labcon;
  90.     lnode->v.i = lab;
  91.     ap = (struct amode *) xalloc(sizeof(struct amode));
  92.     ap->signedflag = 0;
  93.     ap->mode = am_direct;
  94.     ap->offset = lnode;
  95.     return ap;
  96. }
  97.  
  98. struct amode   *
  99. make_immed(i)
  100.  
  101. /*
  102.  * make a node to reference an immediate value i.
  103.  */
  104.     long            i;
  105. {
  106.     struct amode   *ap;
  107.     struct enode   *ep;
  108.  
  109.     ep = (struct enode *) xalloc(sizeof(struct enode));
  110.     ep->signedflag = 1;
  111.     ep->nodetype = en_icon;
  112.     ep->v.i = i;
  113.     ap = (struct amode *) xalloc(sizeof(struct amode));
  114.     ap->signedflag = 1;
  115.     ap->mode = am_immed;
  116.     ap->offset = ep;
  117.     return ap;
  118. }
  119.  
  120. struct amode   *
  121. make_offset(node)
  122.  
  123. /*
  124.  * make a direct reference to a node.
  125.  */
  126.     struct enode   *node;
  127. {
  128.     struct amode   *ap;
  129.  
  130.     if (node == NULL) {
  131.         fprintf( stderr, "DIAG -- null node in make_offset.\n" );
  132.         return NULL;
  133.     }
  134.  
  135.     ap = (struct amode *) xalloc(sizeof(struct amode));
  136.     ap->signedflag = node->signedflag;
  137.     ap->mode = am_direct;
  138.     ap->offset = node;
  139.     return ap;
  140. }
  141.  
  142. struct amode   *
  143. make_delta(ap1, delta)
  144.     struct amode   *ap1;
  145.     int             delta;
  146. {
  147.     if (ap1 == NULL || delta == 0)
  148.         return (ap1);
  149.  
  150.     switch (ap1->mode) {
  151.     case am_immed:
  152.         ap1 = make_offset(ap1->offset); /* FALL THROUGH */
  153.     case am_direct:
  154.         ap1->offset = makenode(en_add, ap1->offset,
  155.                        makenode(en_icon, delta, NULL));
  156.         break;
  157.     case am_ind:
  158.         ap1->mode = am_indx;    /* 0(Ax) */
  159.         ap1->offset = makenode(en_icon, delta, NULL);
  160.         break;
  161.     case am_indx:
  162.         if (ap1->offset->nodetype == en_icon)
  163.             ap1->offset = makenode(en_icon, (ap1->offset->v.i) + delta, NULL);
  164.         break;
  165.     default:
  166.         fprintf( stderr, "DIAG -- uncoded operand in make_delta\n" );
  167.         break;
  168.     }
  169.     return (ap1);
  170. }
  171.  
  172. void
  173. make_legal(ap, flags, size)
  174.  
  175. /*
  176.  * make_legal will coerce the addressing mode in ap1 into a mode that is
  177.  * satisfactory for the flag word.
  178.  */
  179.     struct amode   *ap;
  180.     int             flags, size;
  181. {
  182.     struct amode   *ap2, *ap3;
  183.  
  184.     if (ap == NULL) {
  185.         fprintf( stderr, "DIAG -- NULL pointer in make_legal\n" );
  186.         return;
  187.     }
  188.  
  189.     if (((flags & F_VOL) == 0) || ap->tempflag) {
  190.         switch (ap->mode) {
  191.         case am_immed:
  192.             if (flags & F_IMMED)
  193.                 if (ap->offset != NULL && ap->offset->nodetype != en_autocon)
  194.                     return; /* mode ok */
  195.             break;
  196.         case am_areg:
  197.             if (flags & F_AREG)
  198.                 return;
  199.             break;
  200.         case am_dreg:
  201.             if (flags & F_DREG)
  202.                 return;
  203.             break;
  204.         case am_ind:
  205.         case am_indx:
  206.         case am_indx2:
  207.         case am_xpc:
  208.         case am_direct:
  209.         case am_indx3:
  210.             if (flags & F_MEM)
  211.                 return;
  212.             break;
  213.         case am_freg:
  214.             if (flags & F_FREG)
  215.                 return;
  216.             break;
  217.         }
  218.     }
  219.     if (flags & F_DREG) {
  220.         freeop(ap); /* maybe we can use it... */
  221.         ap2 = temp_data();  /* allocate to dreg */
  222.         if (ap->mode == am_immed && ap->offset->nodetype != en_icon) {
  223.             ap3 = temp_addr();
  224.             gen_code(op_move, size, ap, ap3);
  225.             gen_code(op_move, size, ap3, ap2);
  226.             freeop(ap3);
  227.         }
  228.         else {
  229.             if (!ap->signedflag)
  230.                 gen_code(op_move, 4, make_immed((long) 0), ap2);
  231.             if (ap->mode != am_areg || size != 1)
  232.                 gen_code(op_move, size, ap, ap2);
  233.             else {  /* Can't do "move.b A0,D0" */
  234.                 gen_code(op_move, 2, ap, ap2);
  235.                 gen_code(op_and, 4, make_immed((long) 0xff), ap2);
  236.             }
  237.         }
  238.         ap->mode = ap2->mode;
  239.         ap->preg = ap2->preg;
  240.         ap->sreg = ap2->sreg;
  241.         ap->deep = ap2->deep;
  242.         ap->signedflag = ap2->signedflag;
  243.         ap->tempflag = 1;
  244.         return;
  245.     }
  246.  
  247.     if (flags & F_FREG) {
  248.         if (ap->mode == am_areg || ap->mode == am_dreg)
  249.             fprintf( stderr, "DIAG -- Error in make_legal\n" );
  250.         else {
  251.             ap3 = temp_float();
  252.             freeop(ap);
  253.             ap2 = copy_addr(ap);
  254.             gen_code(op_move, 4, ap2, makedreg((enum e_am) 0));
  255.             ap2 = make_delta(ap2, 4);
  256.             gen_code(op_move, 4, ap2, makedreg((enum e_am) 1));
  257.  
  258.             ap->mode = ap3->mode;
  259.             ap->preg = ap3->preg;
  260.             ap->sreg = ap3->sreg;
  261.             ap->deep = ap3->deep;
  262.             ap->signedflag = ap3->signedflag;
  263.             ap->tempflag = 1;
  264.         }
  265.         return;
  266.     }
  267.  
  268.     /* Must be (flags & F_AREG) */
  269.  
  270.     if (size == 1) {
  271.         ap2 = temp_data();
  272.         if (!ap->signedflag)
  273.             gen_code(op_move, 4, make_immed((long) 0), ap2);
  274.         gen_code(op_move, 1, ap, ap2);
  275.         if (ap->signedflag)
  276.             gen_code(op_ext, 2, ap2, NULL);
  277.  
  278.         freeop( ap );
  279.  
  280.         ap3 = temp_addr();
  281.         gen_code(op_move, 2, ap2, ap3);
  282.         freeop(ap2);
  283.  
  284.         ap->mode = ap3->mode;
  285.         ap->preg = ap3->preg;
  286.         ap->sreg = ap3->sreg;
  287.         ap->deep = ap3->deep;
  288.         ap->signedflag = ap3->signedflag;
  289.         ap->tempflag = 1;
  290.         return;
  291.     }
  292.  
  293.     freeop(ap);
  294.     ap2 = temp_addr();
  295.     if (!equal_address(ap, ap2))
  296.         gen_code(op_move, size, ap, ap2);
  297.  
  298.     ap->mode = ap2->mode;
  299.     ap->preg = ap2->preg;
  300.     ap->sreg = ap2->sreg;
  301.     ap->deep = ap2->deep;
  302.     ap->signedflag = ap2->signedflag;
  303.     ap->tempflag = 1;
  304. }
  305.  
  306. void
  307. do_extend(ap, isize, osize, flags, is_signed)
  308.  
  309. /*
  310.  * if isize is not equal to osize then the operand ap will be loaded into a
  311.  * register (if not already) and if osize is greater than isize it will be
  312.  * extended to match.
  313.  */
  314.     struct amode   *ap;
  315.     int             isize, osize, flags, is_signed;
  316. {
  317.     struct amode   *ap1;
  318.  
  319.     if (ap == NULL) {
  320.         fprintf( stderr, "DIAG -- null node in do_extend.\n" );
  321.         return;
  322.     }
  323.  
  324.     if (isize == osize)
  325.         return;
  326.  
  327.     if (ap->mode != am_areg && ap->mode != am_dreg)
  328.         make_legal(ap, flags & (F_AREG | F_DREG), isize);
  329.  
  330.     if (ap->mode == am_areg) {
  331.         if (is_signed)
  332.             return; /* extend is automagic */
  333.         ap1 = temp_addr();
  334.         gen_code(op_move, 4, make_immed((long) 0), ap1);
  335.         gen_code(op_move, isize, ap, ap1);
  336.         freeop(ap);
  337.         ap->preg = ap1->preg;
  338.         ap->deep = ap1->deep;
  339.     }
  340.  
  341.     if (is_signed) {
  342.         switch (isize) {
  343.         case 1:
  344.             gen_code(op_ext, 2, ap, NULL);
  345.         case 2:
  346.             if (osize == 4)
  347.                 gen_code(op_ext, 4, ap, NULL);
  348.         }
  349.         ap->signedflag = 1;
  350.     }
  351.     else {
  352.         if (ap->signedflag) {
  353.             ap1 = temp_data();
  354.             gen_code(op_move, 4, make_immed((long) 0), ap1);
  355.             gen_code(op_move, isize, ap, ap1);
  356.             gen_code(op_move, 4, ap1, ap);
  357.             freeop(ap1);
  358.         }
  359.         ap->signedflag = 0;
  360.     }
  361. }
  362.  
  363. int
  364. isshort(node)
  365.  
  366. /*
  367.  * return true if the node passed can be generated as a short offset.
  368.  */
  369.     struct enode   *node;
  370. {
  371.     if (node == NULL) {
  372.         fprintf( stderr, "DIAG -- null node in isshort.\n" );
  373.         return FALSE;
  374.     }
  375.     return node->nodetype == en_icon &&
  376.         (node->v.i >= -32767 && node->v.i <= 32767);
  377. }
  378.  
  379. int
  380. isbyte(node)
  381.  
  382. /*
  383.  * return trues if the node passed can be evaluated as a byte offset.
  384.  */
  385.     struct enode   *node;
  386. {
  387.     if (node == NULL) {
  388.         fprintf( stderr, "DIAG -- null node in isbyte.\n" );
  389.         return FALSE;
  390.     }
  391.     return node->nodetype == en_icon &&
  392.         (-128 <= node->v.i && node->v.i <= 127);
  393. }
  394.  
  395. struct amode   *
  396. gen_extend(node, flags, size)
  397.     struct enode   *node;
  398.     int             flags, size;
  399. {
  400.     struct amode   *ap1;
  401.     int             siz1, siz2, is_signed;
  402.  
  403.     if (node == NULL) {
  404.         fprintf( stderr, "DIAG -- null node in gen_extend.\n" );
  405.         return NULL;
  406.     }
  407.  
  408.  
  409.     siz1 = size;
  410.     siz2 = 4;
  411.     is_signed = 1;
  412.  
  413.     switch (node->v.p[0]->nodetype) {
  414.     case en_ub_ref:
  415.         is_signed = 0;  /* Fall through */
  416.     case en_b_ref:
  417.         siz1 = 1;
  418.         break;
  419.     case en_uw_ref:
  420.         is_signed = 0;  /* Fall through */
  421.     case en_w_ref:
  422.         siz1 = 2;
  423.         break;
  424.     case en_tempref:
  425.         is_signed = node->signedflag;
  426.         break;
  427.     }
  428.  
  429.     switch (node->nodetype) {
  430.     case en_cbl:
  431.         siz1 = 1;
  432.         siz2 = 4;
  433.         break;
  434.     case en_cwl:
  435.         siz1 = 2;
  436.         siz2 = 4;
  437.         break;
  438.     }
  439.  
  440.     ap1 = gen_expr(node->v.p[0], flags, siz1);
  441.     do_extend(ap1, siz1, siz2, flags, is_signed);
  442.     make_legal(ap1, flags, siz2);
  443.  
  444.     return (ap1);
  445. }
  446.  
  447. struct amode   *
  448. gen_index(node)
  449.  
  450. /*
  451.  * generate code to evaluate an index node (^+) and return the addressing
  452.  * mode of the result. This routine takes no flags since it always returns
  453.  * either am_ind or am_indx.
  454.  */
  455.     struct enode   *node;
  456. {
  457.     struct amode   *ap1, *ap2, *ap3;
  458.  
  459.     if (node == NULL) {
  460.         fprintf( stderr, "DIAG -- null node in gen_index.\n" );
  461.         return NULL;
  462.     }
  463.     if (node->v.p[0]->nodetype == en_tempref &&
  464.         node->v.p[1]->nodetype == en_tempref &&
  465.         (node->v.p[0]->v.i >= 8 || node->v.p[1]->v.i >= 8)) {
  466.         /* both nodes are registers, one is address */
  467.         if (node->v.p[0]->v.i < 8) {
  468.             ap1 = gen_expr(node->v.p[1], F_AREG, 4);
  469.             make_legal(ap1, F_AREG, 4);
  470.             ap1->sreg = (enum e_am) (node->v.p[0]->v.i);
  471.             ap1->mode = am_indx2;   /* 0(Ax,Dx) */
  472.             ap1->offset = makenode(en_icon, NULL, NULL);
  473.             return ap1;
  474.         }
  475.         ap1 = gen_expr(node->v.p[0], F_AREG, 4);
  476.         make_legal(ap1, F_AREG, 4);
  477.         ap2 = gen_expr(node->v.p[1], F_AREG | F_DREG, 4);
  478.         make_legal(ap1, F_AREG | F_DREG, 4);
  479.         if (ap2->mode == am_dreg) {
  480.             ap1->mode = am_indx2;
  481.             ap1->sreg = ap2->preg;
  482.             ap1->deep = ap2->deep;
  483.         }
  484.         else {
  485.             ap1->mode = am_indx3;
  486.             ap1->sreg = ap2->preg;
  487.             ap1->deep = ap2->deep;
  488.         }
  489.         ap1->offset = makenode(en_icon, NULL, NULL);
  490.         return ap1;
  491.     }
  492.  
  493.     ap1 = gen_expr(node->v.p[0], F_AREG | F_IMMED, 4);
  494.     make_legal(ap1, F_AREG | F_IMMED, 4);
  495.  
  496.     if (ap1->mode == am_immed && isshort(ap1->offset)) {
  497.         ap2 = gen_expr(node->v.p[1], F_AREG, 4);
  498.         make_legal( ap2, F_AREG, 4 );
  499.         ap2->mode = am_indx;
  500.         ap2->offset = ap1->offset;
  501.         return ap2;
  502.     }
  503.  
  504.     make_legal(ap1, F_AREG, 4);
  505.     ap2 = gen_expr(node->v.p[1], F_ALL, 4); /* get right op */
  506.  
  507.     if ((ap2->mode == am_immed && isshort(ap2->offset))
  508.          && ap1->mode == am_areg) { /* make am_indx */
  509.         freeop(ap2);
  510.         freeop(ap1);
  511.         ap1 = request_reg(ap1);
  512.         ap1->mode = am_indx;
  513.         ap1->offset = ap2->offset;
  514.         return ap1;
  515.     }
  516.  
  517.     validate(ap2);
  518.     validate(ap1);
  519.  
  520.     if (istemp(ap1)) {
  521.         gen_code(op_add, 4, ap2, ap1);  /* add left to address reg  */
  522.         ap1->mode = am_ind; /* make indirect        */
  523.         freeop(ap2);    /* release any temps in ap2 */
  524.         return ap1; /* return indirect      */
  525.     }
  526.     else if (istemp(ap2)) {
  527.         make_legal(ap2, F_AREG, 4);
  528.         gen_code(op_add, 4, ap1, ap2);  /* add right to address reg */
  529.         ap2->mode = am_ind; /* make indirect        */
  530.         freeop(ap2);
  531.         freeop(ap1);
  532.         ap1 = request_reg(ap2);
  533.         return ap1; /* return indirect      */
  534.     }
  535.     else {
  536.         ap3 = temp_addr();
  537.         gen_code(op_move, 4, ap1, ap3);
  538.         gen_code(op_add, 4, ap2, ap3);  /* add left to address reg  */
  539.         ap3->mode = am_ind;             /* make indirect        */
  540.         freeop(ap3);
  541.         freeop(ap2);                    /* release any temps in ap2 */
  542.         freeop(ap1);
  543.         ap1 = request_reg(ap3);
  544.         return ap1;                     /* return indirect      */
  545.     }
  546. }
  547.  
  548.  
  549. struct amode   *
  550. make_autocon(lab)
  551.     int             lab;
  552. {
  553.     struct amode   *ap1;
  554.  
  555.     ap1 = (struct amode *) xalloc(sizeof(struct amode));
  556.     ap1->signedflag = 1;
  557.     ap1->mode = am_indx;
  558.     ap1->preg = (enum e_am) Options.Frame;
  559.     ap1->deep = 0;
  560.     ap1->offset = makenode(en_icon, (long) lab, NULL);
  561.     return ap1;
  562. }
  563.  
  564.  
  565. struct amode   *
  566. gen_deref(node, flags, size)
  567.  
  568. /*
  569.  * return the addressing mode of a dereferenced node.
  570.  */
  571.     struct enode   *node;
  572.     int             flags, size;
  573. {
  574.     struct amode   *ap1, *ap2;
  575.     int             siz1;
  576.     int             is_signed;
  577.  
  578.     if (node == NULL) {
  579.         fprintf( stderr, "DIAG -- null node in gen_deref.\n" );
  580.         return NULL;
  581.     }
  582.  
  583.     is_signed = 1;
  584.  
  585.     switch (node->nodetype) {   /* get load size */
  586.     case en_ub_ref:
  587.         is_signed = 0;  /* Fall through */
  588.     case en_b_ref:
  589.         siz1 = 1;
  590.         break;
  591.     case en_uw_ref:
  592.         is_signed = 0;  /* Fall through */
  593.     case en_w_ref:
  594.         siz1 = 2;
  595.         break;
  596.     case en_ul_ref:
  597.         is_signed = 0;  /* Fall through */
  598.     case en_l_ref:
  599.     case en_m_ref:
  600.     case en_f_ref:
  601.         siz1 = 4;
  602.         break;
  603.     case en_d_ref:
  604.         siz1 = 8;
  605.         break;
  606.     }
  607.  
  608.     if (node->nodetype == en_d_ref) {
  609.         ap1 = gen_expr(node->v.p[0], F_ALL, 4);
  610.         if (ap1->mode == am_areg) {
  611.             ap1->signedflag = 1;
  612.             ap1->mode = am_indx;
  613.             ap1->offset = makenode(en_icon, (long) 0, NULL);
  614.             return ap1;
  615.         }
  616.         ap2 = temp_addr();
  617.         gen_code(op_move, 4, ap1, ap2);
  618.         freeop(ap1);
  619.         ap2->signedflag = 1;
  620.         ap2->mode = am_indx;
  621.         ap2->offset = makenode(en_icon, (long) 0, NULL);
  622.         return ap2;
  623.     }
  624.  
  625.     if (node->v.p[0]->nodetype == en_add) {
  626.         ap1 = gen_index(node->v.p[0]);
  627.         do_extend(ap1, siz1, size, flags, is_signed);
  628.         make_legal(ap1, flags, size);
  629.         return ap1;
  630.     }
  631.     else if (node->v.p[0]->nodetype == en_autocon) {
  632.         ap1 = (struct amode *) xalloc(sizeof(struct amode));
  633.         ap1->signedflag = node->v.p[0]->signedflag;
  634.         ap1->mode = am_indx;
  635.         ap1->preg = (enum e_am) Options.Frame;
  636.         ap1->deep = 0;
  637.         ap1->offset = makenode(en_icon, (long) (node->v.p[0]->v.i), NULL);
  638.         do_extend(ap1, siz1, size, flags, is_signed);
  639.         make_legal(ap1, flags, size);
  640.         return ap1;
  641.     }
  642.  
  643.     ap1 = gen_expr(node->v.p[0], F_AREG | F_IMMED, 4);  /* generate address */
  644.     make_legal(ap1, F_AREG | F_IMMED, 4);
  645.  
  646.     if (ap1->mode == am_areg) {
  647.         ap1->mode = am_ind;
  648.         do_extend(ap1, siz1, size, flags, is_signed);
  649.         make_legal(ap1, flags, size);
  650.         return ap1;
  651.     }
  652.     ap1->mode = am_direct;
  653.     do_extend(ap1, siz1, size, flags, is_signed);
  654.     make_legal(ap1, flags, size);
  655.     return ap1;
  656. }
  657.  
  658. struct amode   *
  659. gen_unary(node, flags, size, op)
  660.  
  661. /*
  662.  * generate code to evaluate a unary minus or complement.
  663.  */
  664.     struct enode   *node;
  665.     int             flags, size;
  666.     enum e_op       op;
  667. {
  668.     struct amode   *ap, *ap3;
  669.  
  670.     if (node == NULL) {
  671.         fprintf( stderr, "DIAG -- null node in gen_unary.\n" );
  672.         return NULL;
  673.     }
  674.  
  675.     ap = gen_expr(node->v.p[0], F_DREG, size);
  676.     make_legal(ap, F_DREG, 4);
  677.  
  678.     if (istemp(ap)) {
  679.         gen_code(op, size, ap, NULL);
  680.         make_legal(ap, flags, size);
  681.         return ap;
  682.     }
  683.  
  684.     ap3 = temp_data();
  685.  
  686.     gen_code(op_move, size, ap, ap3);
  687.     freeop(ap);
  688.     gen_code(op, size, ap3, NULL);
  689.     make_legal(ap3, flags, size);
  690.     return ap3;
  691. }
  692.  
  693. struct amode   *
  694. gen_binary(node, flags, size, op)
  695.  
  696. /*
  697.  * generate code to evaluate a binary node and return the addressing mode of
  698.  * the result.
  699.  */
  700.     struct enode   *node;
  701.     int             flags, size;
  702.     enum e_op       op;
  703. {
  704.     struct amode   *ap1, *ap2, *ap3;
  705.  
  706.     if (node == NULL) {
  707.         fprintf( stderr, "DIAG -- null node in gen_binary.\n" );
  708.         return NULL;
  709.     }
  710.  
  711.     if (size == 8)      /* If part of a double expression do in
  712.                  * integer */
  713.         size = 4;
  714.  
  715.     ap1 = gen_expr(node->v.p[0], F_DREG, size);
  716.     make_legal(ap1, F_DREG, size);
  717.     ap2 = gen_expr(node->v.p[1], F_DREG | F_IMMED | F_MEM, size);
  718.     make_legal(ap2, F_DREG | F_IMMED | F_MEM, size);
  719.  
  720.     if (istemp(ap1)) {
  721.         validate(ap1);  /* in case push occurred */
  722.         gen_code(op, size, ap2, ap1);
  723.         freeop(ap2);
  724.         make_legal(ap1, flags, size);
  725.         return ap1;
  726.     }
  727.  
  728.     if (flags & F_DREG)
  729.         ap3 = temp_data();
  730.     else
  731.         ap3 = temp_addr();
  732.  
  733.     validate(ap1);      /* in case push occurred */
  734.  
  735.     gen_code(op_move, size, ap1, ap3);
  736.     gen_code(op, size, ap2, ap3);
  737.  
  738.     if (istemp(ap2)) {
  739.         gen_code(op_move, size, ap3, ap2);
  740.         freeop(ap3);
  741.         freeop(ap2);
  742.         freeop(ap1);
  743.         ap2 = request_reg(ap2);
  744.         make_legal(ap2, flags, size);
  745.         return ap2;
  746.     }
  747.  
  748.     freeop(ap3);
  749.     freeop(ap2);
  750.     freeop(ap1);
  751.     ap3 = request_reg(ap3);
  752.     make_legal(ap3, flags, size);
  753.     return ap3;
  754. }
  755.  
  756. struct amode   *
  757. gen_xbin(node, flags, size, op)
  758.  
  759. /*
  760.  * generate code to evaluate a restricted binary node and return the
  761.  * addressing mode of the result.
  762.  */
  763.     struct enode   *node;
  764.     int             flags, size;
  765.     enum e_op       op;
  766. {
  767.     struct amode   *ap1, *ap2, *ap3;
  768.  
  769.     if (node == NULL) {
  770.         fprintf( stderr, "DIAG -- null node in gen_xbin.\n" );
  771.         return NULL;
  772.     }
  773.  
  774.     ap1 = gen_expr(node->v.p[0], F_DREG, size);
  775.     make_legal(ap1, F_DREG, size);
  776.     ap2 = gen_expr(node->v.p[1], F_DREG, size);
  777.     make_legal(ap2, F_DREG, size);
  778.  
  779.     if (istemp(ap1)) {
  780.         validate(ap1);  /* in case push occurred */
  781.         gen_code(op, size, ap2, ap1);
  782.         freeop(ap2);
  783.         make_legal(ap1, flags, size);
  784.         return ap1;
  785.     }
  786.  
  787.     ap3 = temp_data();
  788.  
  789.     validate(ap1);      /* in case push occurred */
  790.  
  791.     gen_code(op_move, size, ap1, ap3);
  792.     freeop(ap1);
  793.     gen_code(op, size, ap2, ap3);
  794.     freeop(ap2);
  795.     make_legal(ap3, flags, size);
  796.     return ap3;
  797. }
  798.  
  799. struct amode   *
  800. gen_shift(node, flags, size, op)
  801.  
  802. /*
  803.  * generate code to evaluate a shift node and return the address mode of the
  804.  * result.
  805.  */
  806.     struct enode   *node;
  807.     int             flags, size;
  808.     enum e_op       op;
  809. {
  810.     struct amode   *ap1, *ap2, *ap3;
  811.     struct enode   *ep1;
  812.  
  813.     if (node == NULL) {
  814.         fprintf( stderr, "DIAG -- null node in gen_shift.\n" );
  815.         return NULL;
  816.     }
  817.  
  818.     ap1 = gen_expr(node->v.p[0], F_DREG, size);
  819.     make_legal(ap1, F_DREG, size);
  820.  
  821.     ep1 = node->v.p[1];
  822.     if (ep1->nodetype == en_icon && ep1->v.i > 8) {
  823.         ap2 = gen_expr(ep1, F_DREG, 4);
  824.         make_legal(ap2, F_DREG, 4);
  825.     }
  826.     else {
  827.         ap2 = gen_expr(ep1, F_DREG | F_IMMED, 4);
  828.         make_legal(ap2, F_DREG | F_IMMED, 4);
  829.     }
  830.  
  831.     if (istemp(ap1)) {
  832.         validate(ap1);  /* in case push occurred */
  833.         gen_code(op, size, ap2, ap1);
  834.         freeop(ap2);
  835.         make_legal(ap1, flags, size);
  836.         return ap1;
  837.     }
  838.  
  839.     validate(ap2);
  840.     validate(ap1);      /* in case push occurred */
  841.  
  842.     ap3 = temp_data();
  843.  
  844.     gen_code(op_move, size, ap1, ap3);
  845.     gen_code(op, size, ap2, ap3);
  846.  
  847.     make_legal(ap3, flags, size);
  848.  
  849.     freeop(ap3);
  850.     freeop(ap2);
  851.     freeop(ap1);
  852.  
  853.     ap3 = request_reg(ap3);
  854.  
  855.     return ap3;
  856. }
  857.  
  858. void
  859. swap_nodes(node)
  860.  
  861. /*
  862.  * exchange the two operands in a node.
  863.  */
  864.     struct enode   *node;
  865. {
  866.     struct enode   *temp;
  867.  
  868.     if (node == NULL) {
  869.         fprintf( stderr, "DIAG -- null node in swap_nodes.\n" );
  870.         return;
  871.     }
  872.     temp = node->v.p[0];
  873.     node->v.p[0] = node->v.p[1];
  874.     node->v.p[1] = temp;
  875. }
  876.  
  877. struct amode   *
  878. gen_modiv(node, flags, size, op )
  879.  
  880. /*
  881.  * generate code to evaluate a mod operator or a divide operator. these
  882.  * operations are done on only long divisors and word dividends so that the
  883.  * 68000 div instruction can be used.
  884.  */
  885.     struct enode   *node;
  886.     int             flags, size;
  887.     enum e_op       op;
  888. {
  889.     struct amode   *ap1, *ap2, *ap3;
  890.  
  891.     if (node == NULL) {
  892.         fprintf( stderr, "DIAG -- null node in gen_modiv.\n" );
  893.         return NULL;
  894.     }
  895.  
  896.     ap1 = gen_expr(node->v.p[0], F_ALL, 4);
  897.     ap2 = gen_expr(node->v.p[1], F_ALL, 4);
  898.     validate(ap1);
  899.  
  900.     if (Options.MulDiv32) {
  901.         gen_code(op_move, 4, ap2, push);
  902.         gen_code(op_move, 4, ap1, push);
  903.         freeop(ap2);
  904.         freeop(ap1);
  905.  
  906.         switch (op) {
  907.         case op_mods:
  908.             call_library(".lmods");
  909.             break;
  910.         case op_modu:
  911.             call_library( ".lmodu" );
  912.             break;
  913.         case op_divs:
  914.             call_library(".ldivs");
  915.             break;
  916.         case op_divu:
  917.             call_library( ".ldivu" );
  918.             break;
  919.         }
  920.  
  921.         ap3 = temp_data();
  922.         gen_code(op_move, 4, pop, ap3);
  923.         gen_code(op_add, 4, make_immed((long) 4), makeareg(am_xpc));
  924.         return (ap3);
  925.     }
  926.  
  927.     make_legal(ap1, F_DREG, 4);
  928.     make_legal(ap2, F_DREG, 4);
  929.     validate(ap1);
  930.  
  931.     if (istemp(ap1)) {
  932.  
  933.         switch (op) {
  934.         case op_divs:
  935.         case op_mods:
  936.             gen_code(op_divs, 0, ap2, ap1);
  937.             break;
  938.         case op_divu:
  939.         case op_modu:
  940.             gen_code(op_divu, 0, ap2, ap1);
  941.             break;
  942.         }
  943.  
  944.         if (op == op_modu || op == op_mods)
  945.             gen_code(op_swap, 0, ap1, NULL);
  946.  
  947.         gen_code(op_ext, 4, ap1, NULL);
  948.         make_legal(ap1, flags, 4);
  949.         freeop(ap2);
  950.         return ap1;
  951.     }
  952.  
  953.     ap3 = temp_data();
  954.     gen_code(op_move, size, ap1, ap3);
  955.  
  956.     switch (op) {
  957.     case op_divs:
  958.     case op_mods:
  959.         gen_code(op_divs, 0, ap2, ap3);
  960.         break;
  961.     case op_divu:
  962.     case op_modu:
  963.         gen_code(op_divu, 0, ap2, ap3);
  964.         break;
  965.     }
  966.  
  967.     if (op == op_modu || op == op_mods)
  968.         gen_code(op_swap, 0, ap3, NULL);
  969.  
  970.     gen_code(op_ext, 4, ap3, NULL);
  971.  
  972.     freeop(ap3);
  973.     freeop(ap2);
  974.     freeop(ap1);
  975.  
  976.     ap3 = request_reg(ap3);
  977.     make_legal(ap3, flags, 4);
  978.     return ap3;
  979. }
  980.  
  981. struct amode   *
  982. gen_mul(node, flags, size, op)
  983.  
  984. /*
  985.  * generate code to evaluate a multiply node. both operands are treated as
  986.  * words and the result is long and is always in a register so that the 68000
  987.  * mul instruction can be used.
  988.  */
  989.     struct enode   *node;
  990.     int             flags, size;
  991.     enum e_op       op;
  992. {
  993.     struct amode   *ap1, *ap2, *ap3;
  994.     int             i, b2, bits, mask, last;
  995.  
  996.     if (node == NULL) {
  997.         fprintf( stderr, "DIAG -- null node in gen_mul.\n" );
  998.         return NULL;
  999.     }
  1000.  
  1001.     if (node->v.p[0]->nodetype == en_icon)
  1002.         swap_nodes(node);
  1003.  
  1004.     ap1 = gen_expr(node->v.p[0], F_ALL, 4);
  1005.     ap2 = gen_expr(node->v.p[1], F_ALL, 4);
  1006.     validate(ap1);
  1007.  
  1008.     if (ap2->mode == am_immed && ap2->offset->nodetype == en_icon) {
  1009.         /* Recode the multiplier */
  1010.         bits = 0;
  1011.         mask = ap2->offset->v.i;
  1012.         for (i = 0; i < 32; i++) {
  1013.             if ((mask >> i) & 1)
  1014.                 ++bits;
  1015.         }
  1016.         if (bits >= 1 && bits < 24 && mask > 0 && Options.Optimize) {
  1017.             if (!istemp(ap1)) {
  1018.                 ap3 = temp_data();
  1019.                 gen_code(op_move, size, ap1, ap3);
  1020.                 freeop(ap1);
  1021.                 ap1 = ap3;
  1022.             }
  1023.             ap3 = temp_data();
  1024.             for (bits = 0; (mask & (1 << bits)) == 0; bits++);
  1025.             b2 = bits;
  1026.             while (b2 > MAX_SHIFT) {
  1027.                 gen_code(op_asl, 4, make_immed((long) MAX_SHIFT), ap1);
  1028.                 b2 -= MAX_SHIFT;
  1029.             }
  1030.             if (b2 != 0)
  1031.                 gen_code(op_asl, 4, make_immed((long) b2), ap1);
  1032.             gen_code(op_move, 4, ap1, ap3);
  1033.             last = bits;
  1034.             for (++bits; bits < 32; ++bits) {
  1035.                 if ((mask & (1 << bits)) != 0) {
  1036.                     b2 = (bits - last);
  1037.                     while (b2 > MAX_SHIFT) {
  1038.                         gen_code(op_asl, 4, make_immed((long) MAX_SHIFT), ap3);
  1039.                         b2 -= MAX_SHIFT;
  1040.                     }
  1041.                     if (b2 != 0)
  1042.                         gen_code(op_asl, 4, make_immed((long) b2), ap3);
  1043.                     gen_code(op_add, 4, ap3, ap1);
  1044.                     last = bits;
  1045.                 }
  1046.             }
  1047.             freeop(ap3);
  1048.             freeop(ap2);
  1049.             return (ap1);
  1050.         }
  1051.     }
  1052.  
  1053.  
  1054.     if (Options.MulDiv32) {
  1055.         gen_code(op_move, 4, ap2, push);
  1056.         gen_code(op_move, 4, ap1, push);
  1057.         freeop(ap2);
  1058.         freeop(ap1);
  1059.         call_library(".lmuls");
  1060.         ap3 = temp_data();
  1061.         gen_code(op_move, 4, pop, ap3);
  1062.         gen_code(op_add, 4, make_immed((long) 4), makeareg(am_xpc));
  1063.         return (ap3);
  1064.     }
  1065.  
  1066.     make_legal(ap1, F_DREG, 4);
  1067.     make_legal(ap2, F_DREG, 4);
  1068.     validate(ap1);
  1069.  
  1070.     if (istemp(ap1)) {
  1071.         gen_code(op, 0, ap2, ap1);
  1072.         freeop(ap2);
  1073.         make_legal(ap1, flags, 4);
  1074.         return ap1;
  1075.     }
  1076.  
  1077.     ap3 = temp_data();
  1078.     gen_code(op_move, size, ap1, ap3);
  1079.     gen_code(op, 0, ap2, ap3);
  1080.     freeop(ap3);
  1081.     freeop(ap2);
  1082.     freeop(ap1);
  1083.     ap3 = request_reg(ap3);
  1084.     make_legal(ap3, flags, 4);
  1085.     return ap3;
  1086. }
  1087.  
  1088. struct amode   *
  1089. gen_hook(node, flags, size)
  1090.  
  1091. /*
  1092.  * generate code to evaluate a condition operator node (?:)
  1093.  */
  1094.  
  1095.     struct enode   *node;
  1096.     int             flags, size;
  1097. {
  1098.     struct amode   *ap1, *ap2, *ap3;
  1099.     int             siz1, siz2;
  1100.     int             false_label, end_label;
  1101.  
  1102.     if (node == NULL) {
  1103.         fprintf( stderr, "DIAG -- null node in gen_hook.\n" );
  1104.         return NULL;
  1105.     }
  1106.  
  1107.     false_label = nextlabel++;
  1108.     end_label = nextlabel++;
  1109.  
  1110.     flags = (flags & (F_AREG | F_DREG));
  1111.  
  1112.     falsejp(node->v.p[0], false_label);
  1113.     node = node->v.p[1];
  1114.  
  1115.     siz1 = natural_size(node->v.p[0]);
  1116.     siz2 = natural_size(node->v.p[1]);
  1117.  
  1118.     if (siz1 == 8 || siz2 == 8) {
  1119.         flags = F_FREG;
  1120.         size = 8;
  1121.     }
  1122.  
  1123.     ap1 = gen_expr(node->v.p[0], flags, siz1);
  1124.     make_legal(ap1, flags, size);
  1125.  
  1126.     gen_code(op_bra, 0, make_label(end_label), NULL);
  1127.  
  1128.     gen_label(false_label);
  1129.  
  1130.     freeop(ap1);
  1131.  
  1132.     ap2 = gen_expr(node->v.p[1], flags, siz2);
  1133.     make_legal(ap2, flags, size);
  1134.  
  1135.     if (!equal_address(ap1, ap2)) {
  1136.         if (size <= 4)
  1137.             gen_code(op_move, size, ap2, ap1);
  1138.         else {
  1139.             ap3 = copy_addr(ap2);
  1140.             gen_code(op_move, 4, ap3, makedreg((enum e_am) 0));
  1141.             ap3 = make_delta(ap3, 4);
  1142.             gen_code(op_move, 4, ap3, makedreg((enum e_am) 1));
  1143.         }
  1144.     }
  1145.     freeop(ap2);
  1146.     gen_label(end_label);
  1147.     ap1 = request_reg(ap1);
  1148.     return ap1;
  1149. }
  1150.  
  1151. struct amode   *
  1152. gen_asadd(node, flags, size, op)
  1153.  
  1154. /*
  1155.  * generate a plus equal or a minus equal node.
  1156.  */
  1157.     struct enode   *node;
  1158.     int             flags, size;
  1159.     enum e_op       op;
  1160. {
  1161.     struct amode   *ap1, *ap2;
  1162.     int             ssize;
  1163.  
  1164.     if (node == NULL) {
  1165.         fprintf( stderr, "DIAG -- null node in gen_asadd.\n" );
  1166.         return NULL;
  1167.     }
  1168.     ssize = natural_size(node->v.p[0]);
  1169.     if (ssize > size)
  1170.         size = ssize;
  1171.     ap1 = gen_expr(node->v.p[0], F_ALL, ssize);
  1172.     ap2 = gen_expr(node->v.p[1], F_DREG | F_IMMED, size);
  1173.     make_legal(ap2, F_DREG | F_IMMED, size);
  1174.     validate(ap1);
  1175.     gen_code(op, ssize, ap2, ap1);
  1176.     freeop(ap2);
  1177.     do_extend(ap1, ssize, size, flags, 1);
  1178.     make_legal(ap1, flags, size);
  1179.     return ap1;
  1180. }
  1181.  
  1182. struct amode   *
  1183. gen_aslogic(node, flags, size, op)
  1184.  
  1185. /*
  1186.  * generate a and equal or a or equal node.
  1187.  */
  1188.     struct enode   *node;
  1189.     int             flags, size;
  1190.     enum e_op       op;
  1191. {
  1192.     struct amode   *ap1, *ap2, *ap3;
  1193.     int             ssize;
  1194.  
  1195.     if (node == NULL) {
  1196.         fprintf( stderr, "DIAG -- null node in gen_aslogic.\n" );
  1197.         return NULL;
  1198.     }
  1199.     ssize = natural_size(node->v.p[0]);
  1200.     if (ssize > size)
  1201.         size = ssize;
  1202.     ap1 = gen_expr(node->v.p[0], F_ALL, ssize);
  1203.     ap2 = gen_expr(node->v.p[1], F_DREG | F_IMMED, size);
  1204.     make_legal(ap2, F_DREG | F_IMMED, size);
  1205.  
  1206.     validate(ap1);
  1207.  
  1208.     if (ap1->mode != am_areg)
  1209.         gen_code(op, ssize, ap2, ap1);
  1210.     else {
  1211.         ap3 = temp_data();
  1212.         gen_code(op_move, 4, ap1, ap3);
  1213.         gen_code(op, size, ap2, ap3);
  1214.         gen_code(op_move, size, ap3, ap1);
  1215.         freeop(ap3);
  1216.     }
  1217.     freeop(ap2);
  1218.     do_extend(ap1, ssize, size, flags, 1);
  1219.     make_legal(ap1, flags, size);
  1220.     return ap1;
  1221. }
  1222.  
  1223. struct amode   *
  1224. gen_asshift(node, flags, size, op)
  1225.  
  1226. /*
  1227.  * generate shift equals operators.
  1228.  */
  1229.     struct enode   *node;
  1230.     int             flags, size;
  1231.     enum e_op       op;
  1232. {
  1233.     struct amode   *ap1, *ap2, *ap3;
  1234.     struct enode   *ep1;
  1235.  
  1236.     if (node == NULL) {
  1237.         fprintf( stderr, "DIAG -- null node in gen_asshift.\n" );
  1238.         return NULL;
  1239.     }
  1240.  
  1241.     ap1 = gen_expr(node->v.p[0], F_ALL, size);
  1242.     if (ap1->mode != am_dreg) {
  1243.         ap3 = temp_data();
  1244.         gen_code(op_move, size, ap1, ap3);
  1245.     }
  1246.     else
  1247.         ap3 = ap1;
  1248.  
  1249.     ep1 = node->v.p[1];
  1250.     if (ep1->nodetype == en_icon && ep1->v.i > 8) {
  1251.         ap2 = gen_expr(ep1, F_DREG, size);
  1252.         make_legal(ap2, F_DREG, size);
  1253.     }
  1254.     else {
  1255.         ap2 = gen_expr(ep1, F_DREG | F_IMMED, size);
  1256.         make_legal(ap2, F_DREG | F_IMMED, size);
  1257.     }
  1258.  
  1259.     validate(ap3);
  1260.     gen_code(op, size, ap2, ap3);
  1261.     freeop(ap2);
  1262.     if (ap3 != ap1) {
  1263.         gen_code(op_move, size, ap3, ap1);
  1264.         freeop(ap3);
  1265.     }
  1266.     make_legal(ap1, flags, size);
  1267.     return ap1;
  1268. }
  1269.  
  1270. struct amode   *
  1271. gen_asmul(node, flags, size)
  1272.  
  1273. /*
  1274.  * generate a *= node.
  1275.  */
  1276.     struct enode   *node;
  1277.     int             flags, size;
  1278. {
  1279.     struct amode   *ap1, *ap2, *ap3, *ap4;
  1280.     int             mask, b2, bits, i, last, numbits;
  1281.  
  1282.     if (node == NULL) {
  1283.         fprintf( stderr, "DIAG -- null node in gen_asmul.\n" );
  1284.         return NULL;
  1285.     }
  1286.  
  1287.     ap1 = gen_expr(node->v.p[0], F_ALL, 4);
  1288.     ap2 = gen_expr(node->v.p[1], F_ALL, 4);
  1289.     validate(ap1);
  1290.  
  1291.     if (ap2->mode == am_immed && ap2->offset->nodetype == en_icon) {
  1292.         /* Recode the multiplier */
  1293.         bits = 0;   /* A3 = A3 * A1     */
  1294.         mask = ap2->offset->v.i;
  1295.         for (i = 0; i < 32; i++) {
  1296.             if ((mask >> i) & 1)
  1297.                 ++bits;
  1298.         }
  1299.         if (bits >= 1 && bits < 24 && mask > 0 && Options.Optimize) {
  1300.             numbits = bits;
  1301.             ap4 = ap1;
  1302.             if (!istemp(ap1)) {
  1303.                 ap3 = temp_data();
  1304.                 gen_code(op_move, size, ap1, ap3);
  1305.                 ap4 = ap3;
  1306.             }
  1307.             ap3 = temp_data();
  1308.             for (bits = 0; (mask & (1 << bits)) == 0; bits++);
  1309.             if (bits != 0) {
  1310.                 b2 = bits;
  1311.                 while (b2 > MAX_SHIFT) {
  1312.                     gen_code(op_asl, 4, make_immed((long) MAX_SHIFT), ap4);
  1313.                     b2 -= MAX_SHIFT;
  1314.                 }
  1315.                 if (b2 != 0)
  1316.                     gen_code(op_asl, 4, make_immed((long) b2), ap4);
  1317.             }
  1318.             if (numbits > 1)
  1319.                 gen_code(op_move, 4, ap4, ap3);
  1320.             last = bits;
  1321.             for (++bits; bits < 32; ++bits) {
  1322.                 if ((mask & (1 << bits)) != 0) {
  1323.                     b2 = (bits - last);
  1324.                     while (b2 > MAX_SHIFT) {
  1325.                         gen_code(op_asl, 4, make_immed((long) MAX_SHIFT), ap3);
  1326.                         b2 -= MAX_SHIFT;
  1327.                     }
  1328.                     if (b2 != 0)
  1329.                         gen_code(op_asl, 4, make_immed((long) b2), ap3);
  1330.                     gen_code(op_add, 4, ap3, ap4);
  1331.                     last = bits;
  1332.                 }
  1333.             }
  1334.             gen_code(op_move, 4, ap4, ap1);
  1335.             freeop(ap3);
  1336.             freeop(ap2);
  1337.             return (ap1);
  1338.         }
  1339.     }
  1340.  
  1341.     if (Options.MulDiv32) {
  1342.         gen_code(op_move, 4, ap1, push);
  1343.         gen_code(op_move, 4, ap2, push);
  1344.         freeop(ap2);
  1345.         if (node->nodetype == en_asumul)
  1346.             call_library(".lmulu");
  1347.         else
  1348.             call_library(".lmuls");
  1349.         gen_code(op_move, 4, pop, ap1);
  1350.         gen_code(op_add, 4, make_immed((long) 4), makeareg(am_xpc));
  1351.         return (ap1);
  1352.     }
  1353.  
  1354.     make_legal(ap1, F_DREG, 4);
  1355.     make_legal(ap2, F_DREG, 4);
  1356.     validate(ap1);
  1357.  
  1358.     if (istemp(ap1)) {
  1359.         if (node->nodetype == en_asumul)
  1360.             gen_code(op_mulu, 0, ap2, ap1);
  1361.         else
  1362.             gen_code(op_muls, 0, ap2, ap1);
  1363.         return (ap1);
  1364.     }
  1365.     else {
  1366.         ap3 = temp_data();
  1367.         gen_code(op_move, size, ap1, ap3);
  1368.         if (node->nodetype == en_asumul)
  1369.             gen_code(op_mulu, 0, ap2, ap3);
  1370.         else
  1371.             gen_code(op_muls, 0, ap2, ap3);
  1372.         gen_code(op_move, 4, ap3, ap1);
  1373.         freeop(ap3);
  1374.         freeop(ap2);
  1375.         return (ap1);
  1376.     }
  1377. }
  1378.  
  1379. struct amode   *
  1380. gen_asmodiv(node, flags, size, op)
  1381.  
  1382. /*
  1383.  * generate /= and %= nodes.
  1384.  */
  1385.     struct enode   *node;
  1386.     int             flags, size;
  1387.     enum e_op       op;
  1388. {
  1389.     struct amode   *ap1, *ap2, *ap3;
  1390.  
  1391.     if (node == NULL) {
  1392.         fprintf( stderr, "DIAG -- null node in gen_asmodiv.\n" );
  1393.         return NULL;
  1394.     }
  1395.  
  1396.     ap2 = gen_expr(node->v.p[0], F_ALL, 4);
  1397.     ap3 = gen_expr(node->v.p[1], F_ALL, 4);
  1398.     validate(ap2);
  1399.  
  1400.     if (Options.MulDiv32) {
  1401.         gen_code(op_move, 4, ap3, push);
  1402.         gen_code(op_move, 4, ap2, push);
  1403.  
  1404.         switch (op) {
  1405.         case op_mods:
  1406.             call_library(".lmods");
  1407.             break;
  1408.         case op_modu:
  1409.             call_library(".lmodu");
  1410.             break;
  1411.         case op_divs:
  1412.             call_library(".ldivs");
  1413.             break;
  1414.         case op_divu:
  1415.             call_library(".ldivu");
  1416.             break;
  1417.         }
  1418.  
  1419.         gen_code(op_move, 4, pop, ap2);
  1420.         gen_code(op_add, 4, make_immed((long) 4), makeareg(am_xpc));
  1421.         make_legal(ap2, flags, size);
  1422.         freeop(ap3);
  1423.         return (ap2);
  1424.     }
  1425.  
  1426.     ap1 = temp_data();
  1427.     make_legal(ap3, F_DREG, 4);
  1428.  
  1429.     if (istemp(ap2)) {
  1430.         if (op == op_divs || op == op_mods)
  1431.             gen_code(op_divs, 0, ap3, ap2);
  1432.         else
  1433.             gen_code(op_divu, 0, ap3, ap2);
  1434.  
  1435.         if (op == op_mods || op == op_modu)
  1436.             gen_code(op_swap, 0, ap2, NULL);
  1437.  
  1438.         gen_code(op_ext, 4, ap2, NULL);
  1439.         make_legal(ap2, flags, 4);
  1440.         freeop(ap1);
  1441.         freeop(ap3);
  1442.         return ap2;
  1443.     }
  1444.  
  1445.     validate(ap3);
  1446.     validate(ap2);
  1447.  
  1448.     gen_code(op_move, 4, ap2, ap1);
  1449.  
  1450.     if (op == op_divs || op == op_mods)
  1451.         gen_code(op_divs, 0, ap3, ap1);
  1452.     else
  1453.         gen_code(op_divu, 0, ap3, ap1);
  1454.  
  1455.     if (op == op_mods || op == op_modu)
  1456.         gen_code(op_swap, 0, ap1, NULL);
  1457.  
  1458.     gen_code(op_ext, 4, ap1, NULL);
  1459.     gen_code(op_move, 4, ap1, ap2);
  1460.  
  1461.     freeop(ap1);
  1462.     freeop(ap3);
  1463.  
  1464.     make_legal(ap1, flags, size);
  1465.     return ap2;
  1466. }
  1467.  
  1468. struct amode   *
  1469. gen_massign(node, flags, size)
  1470.  
  1471. /*
  1472.  * generate code for an memory assignment node. It requires that an en_m_ref
  1473.  * assignment is passed as the *node parameter
  1474.  */
  1475.  
  1476.     struct enode   *node;
  1477.     int             flags, size;
  1478. {
  1479.     struct enode   *ep1, *ep2;
  1480.     struct amode   *ap1, *ap2, *ap3, *ap4, *ap5;
  1481.     int             ssize, begin_label;
  1482.  
  1483.     flags = F_ALL;
  1484.  
  1485.     ep1 = node->v.p[0];
  1486.     ep2 = node->v.p[1];
  1487.  
  1488.     ap1 = gen_expr(ep1, flags, 4);
  1489.     ap2 = gen_expr(ep2, flags, 4);
  1490.     validate(ap2);
  1491.     validate(ap1);
  1492.  
  1493.     ssize = (ep1->v.p[1]->v.i);
  1494.  
  1495.     if (ssize > size)
  1496.         size = ssize;
  1497.  
  1498.     if (ssize <= 4) {
  1499.         gen_code(op_move, ssize, ap2, ap1);
  1500.         freeop(ap2);
  1501.         freeop(ap1);
  1502.         ap3 = request_reg(ap1);
  1503.         return (ap3);
  1504.     }
  1505.  
  1506.     if (ap2->mode == am_areg || ap2->mode == am_dreg)
  1507.         gen_code(op_move, 4, ap2, push);
  1508.     else
  1509.         gen_code(op_pea, 0, ap2, NULL);
  1510.  
  1511.     if (ap1->mode == am_areg || ap1->mode == am_dreg)
  1512.         gen_code(op_move, 4, ap1, push);
  1513.     else
  1514.         gen_code(op_pea, 0, ap1, NULL);
  1515.  
  1516.     freeop(ap2);
  1517.     freeop(ap1);
  1518.  
  1519.     ap3 = temp_data();
  1520.     ap4 = temp_addr();
  1521.     ap5 = temp_addr();
  1522.  
  1523.     gen_code(op_move, 4, pop, ap5);
  1524.     gen_code(op_move, 4, pop, ap4);
  1525.  
  1526.     ap4->mode = ap5->mode = am_ainc;
  1527.     if (ssize < 16) {
  1528.         while (ssize >= 4) {
  1529.             gen_code(op_move, 4, ap4, ap5);
  1530.             ssize -= 4;
  1531.         }
  1532.     }
  1533.     else {
  1534.         gen_code(op_move, 4, make_immed((long) ssize / 4), ap3);
  1535.         begin_label = nextlabel++;
  1536.         gen_label(begin_label);
  1537.         gen_code(op_move, 4, ap4, ap5);
  1538.         gen_code(op_dbra, 0, ap3, make_label(begin_label));
  1539.         ssize %= 4;
  1540.     }
  1541.     if (ssize >= 2) {
  1542.         gen_code(op_move, 2, ap4, ap5);
  1543.         ssize -= 2;
  1544.     }
  1545.     if (ssize >= 1) {
  1546.         gen_code(op_move, 1, ap4, ap5);
  1547.         ssize -= 1;
  1548.     }
  1549.  
  1550.     freeop(ap5);
  1551.     freeop(ap4);
  1552.     freeop(ap3);
  1553.  
  1554.     ap3 = request_reg(ap1);
  1555.     return (ap3);
  1556. }
  1557.  
  1558. struct amode   *
  1559. gen_assign(node, flags, size)
  1560.  
  1561. /*
  1562.  * generate code for an assignment node. if the size of the assignment
  1563.  * destination is larger than the size passed then everything below this node
  1564.  * will be evaluated with the assignment size.
  1565.  */
  1566.     struct enode   *node;
  1567.     int             flags, size;
  1568. {
  1569.     struct amode   *ap1, *ap2, *ap3, *ap4;
  1570.     int             ssize, is_signed, size1, size2;
  1571.  
  1572.     if (node == NULL) {
  1573.         fprintf( stderr, "DIAG -- null node in gen_assign.\n" );
  1574.         return NULL;
  1575.     }
  1576.  
  1577.     if (node->v.p[0]->nodetype == en_m_ref) {
  1578.         return (gen_massign(node, flags, size));
  1579.     }
  1580.  
  1581.     ssize = size1 = natural_size( node->v.p[0] );
  1582.     size2 = natural_size( node->v.p[1] );
  1583.  
  1584.     switch (node->v.p[0]->nodetype) {
  1585.     case en_ub_ref:
  1586.     case en_uw_ref:
  1587.     case en_ul_ref:
  1588.         is_signed = 0; 
  1589.         break;
  1590.     case en_b_ref:
  1591.     case en_w_ref:
  1592.     case en_l_ref:
  1593.     case en_f_ref:
  1594.     case en_tempref:
  1595.     case en_d_ref:
  1596.         is_signed = 1;
  1597.         break;
  1598.     default:
  1599.         fprintf( stderr, "DIAG -- Uncoded LHS\n" );
  1600.         break;
  1601.     }
  1602.  
  1603.     if (ssize > size)
  1604.         size = ssize;
  1605.  
  1606.     if (ssize == 8) {
  1607.         ap1 = gen_expr(node->v.p[1], F_ALL | F_FREG, size);
  1608.         ap2 = gen_expr(node->v.p[0], F_ALL, size);
  1609.  
  1610.         validate(ap2);
  1611.         validate(ap1);
  1612.  
  1613.         ap4 = copy_addr(ap2);
  1614.         if (ap1->mode == am_freg) {
  1615.             gen_code(op_move, 4, makedreg((enum e_am) 0), ap4);
  1616.             ap4 = make_delta(ap4, 4);
  1617.             gen_code(op_move, 4, makedreg((enum e_am) 1), ap4);
  1618.             freeop(ap2);
  1619.         }
  1620.         else {
  1621.             ap3 = copy_addr(ap1);
  1622.             gen_code(op_move, 4, ap3, ap4);
  1623.             ap3 = make_delta(ap3, 4);
  1624.             ap4 = make_delta(ap4, 4);
  1625.             gen_code(op_move, 4, ap3, ap4);
  1626.             freeop(ap2);
  1627.         }
  1628.         return ap1;
  1629.     }
  1630.     else {
  1631.         ap2 = gen_expr( node->v.p[1], F_ALL,  size2 );
  1632.  
  1633.         if (ap2->mode == am_areg && ssize == 1) 
  1634.             make_legal(ap2, F_DREG, 4); /* Don't allow move.b A0,D0 */
  1635.         else if (ap2->mode == am_immed && ap2->offset->nodetype != en_icon) 
  1636.             make_legal(ap2, F_AREG, 4); /* Don't allow move.l #_label,D0 */
  1637.  
  1638.         if (size2 != size1) {
  1639.             make_legal( ap2, F_AREG | F_DREG, size2 );
  1640.             do_extend( ap2, size2, size1, F_AREG | F_DREG, is_signed );
  1641.         }
  1642.   
  1643.         ap1 = gen_expr( node->v.p[0], F_ALL, size1 );
  1644.  
  1645.         validate(ap1);
  1646.         validate(ap2);
  1647.  
  1648.         if (!node->signedflag && ssize != 4)
  1649.             gen_code(op_move, 4, make_immed((long) 0), ap1);
  1650.  
  1651.         gen_code(op_move, size1, ap2, ap1);
  1652.  
  1653.         freeop(ap1);
  1654.         freeop(ap2);
  1655.  
  1656.         if (ap2->mode == am_immed && ap2->offset->nodetype == en_icon) {
  1657.             if (ap1->mode != am_areg && ap1->mode != am_dreg)   /* x = y = 0 */
  1658.                 return ap2;
  1659.         }
  1660.  
  1661.         ap1 = request_reg(ap1);
  1662.         return ap1;
  1663.     }
  1664. }
  1665.  
  1666. struct amode   *
  1667. gen_aincdec(node, flags, size, op)
  1668.  
  1669. /*
  1670.  * generate an auto increment or decrement node. op should be either op_add
  1671.  * (for increment) or op_sub (for decrement).
  1672.  */
  1673.     struct enode   *node;
  1674.     int             flags, size;
  1675.     enum e_op       op;
  1676. {
  1677.     struct amode   *ap1, *ap2;
  1678.     int             siz1, amount;
  1679.  
  1680.     if (node == NULL) {
  1681.         fprintf( stderr, "DIAG -- null node in gen_aincdec.\n" );
  1682.         return NULL;
  1683.     }
  1684.  
  1685.     siz1 = natural_size(node->v.p[0]);
  1686.  
  1687.     amount = node->v.p[1]->v.i;
  1688.  
  1689.     if (flags & F_NOVALUE) {/* dont need result */
  1690.         ap1 = gen_expr(node->v.p[0], F_ALL, siz1);
  1691.         gen_code(op, siz1, make_immed( amount ), ap1 );
  1692.         freeop(ap1);
  1693.         return NULL;
  1694.     }
  1695.     if (flags & F_DREG)
  1696.         ap2 = temp_data();
  1697.     else
  1698.         ap2 = temp_addr();
  1699.  
  1700.     ap1 = gen_expr(node->v.p[0], F_ALL, siz1);
  1701.     validate(ap1);
  1702.     gen_code(op_move, siz1, ap1, ap2);
  1703.     gen_code(op, siz1, make_immed(amount), ap1 );
  1704.     do_extend(ap1, siz1, size, flags, 1);
  1705.     freeop(ap1);
  1706.     return ap2;
  1707. }
  1708.  
  1709. int
  1710. getsize(node)
  1711.  
  1712. /*
  1713.  * return the (hopefully) base type size of a node.
  1714.  */
  1715.     struct enode   *node;
  1716. {
  1717.     int             siz0, siz1;
  1718.  
  1719.     if (node == NULL)
  1720.         return 0;
  1721.     switch (node->nodetype) {
  1722.     case en_icon:
  1723.         return 4;
  1724.     case en_d_ref:
  1725.     case en_cld:
  1726.     case en_cfd:
  1727.     case en_faddd:
  1728.     case en_fsubd:
  1729.     case en_fmuld:
  1730.     case en_fdivd:
  1731.     case en_fmodd:
  1732.     case en_fnegd:
  1733.     case en_faincd:
  1734.     case en_fadecd:
  1735.         return 8;
  1736.     case en_fcall:
  1737.         return (node->size) < stdint.size ? stdint.size : (node->size);
  1738.     case en_labcon:
  1739.     case en_nacon:
  1740.     case en_autocon:
  1741.     case en_l_ref:
  1742.     case en_ul_ref:
  1743.     case en_tempref:
  1744.     case en_cbl:
  1745.     case en_cwl:
  1746.     case en_clf:
  1747.     case en_cfl:
  1748.     case en_cdl:
  1749.     case en_cdf:
  1750.     case en_f_ref:
  1751.     case en_fadds:
  1752.     case en_fsubs:
  1753.     case en_fmuls:
  1754.     case en_fdivs:
  1755.     case en_fmods:
  1756.     case en_fnegs:
  1757.     case en_faincs:
  1758.     case en_fadecs:
  1759.         return 4;
  1760.     case en_b_ref:
  1761.     case en_ub_ref:
  1762.         return 2;
  1763.     case en_cbw:
  1764.     case en_w_ref:
  1765.     case en_uw_ref:
  1766.         return 2;
  1767.     case en_eq:
  1768.     case en_ne:
  1769.     case en_lt:
  1770.     case en_le:
  1771.     case en_gt:
  1772.     case en_ge:
  1773.     case en_land:
  1774.     case en_lor:
  1775.     case en_not:
  1776.     case en_compl:
  1777.         return 4;
  1778.     case en_uminus:
  1779.     case en_assign:
  1780.     case en_ainc:
  1781.     case en_adec:
  1782.         return getsize(node->v.p[0]);
  1783.     case en_add:
  1784.     case en_sub:
  1785.     case en_mul:
  1786.     case en_umul:
  1787.     case en_div:
  1788.     case en_udiv:
  1789.     case en_mod:
  1790.     case en_umod:
  1791.     case en_and:
  1792.     case en_or:
  1793.     case en_xor:
  1794.     case en_lsh:
  1795.     case en_rsh:
  1796.  
  1797.     case en_asadd:
  1798.     case en_assub:
  1799.     case en_asmul:
  1800.     case en_asdiv:
  1801.     case en_asmod:
  1802.     case en_asumul:
  1803.     case en_asudiv:
  1804.     case en_asumod:
  1805.     case en_asand:
  1806.     case en_asor:
  1807.     case en_aseor:
  1808.     case en_aslsh:
  1809.     case en_asrsh:
  1810.         siz0 = getsize(node->v.p[0]);
  1811.         siz1 = getsize(node->v.p[1]);
  1812.         if (siz1 > siz0)
  1813.             return siz1;
  1814.         else
  1815.             return siz0;
  1816.     case en_void:
  1817.     case en_cond:
  1818.         return getsize(node->v.p[1]);
  1819.     default:
  1820.         fprintf( stderr, "DIAG -- getsize error.\n" );
  1821.         break;
  1822.     }
  1823.     return 0;
  1824. }
  1825.  
  1826. int
  1827. push_param(ep, size)
  1828.  
  1829. /*
  1830.  * push the operand expression onto the stack. Return size pushed
  1831.  */
  1832.     struct enode   *ep;
  1833.     int             size;
  1834. {
  1835.     struct amode   *ap1, *ap2;
  1836.  
  1837.     if (ep == NULL) {
  1838.         fprintf( stderr, "DIAG -- NULL pointer in push_param\n" );
  1839.         return (0);
  1840.     }
  1841.  
  1842.     if (size == 8)
  1843.         ap1 = gen_expr(ep, F_ALL | F_FREG, size);
  1844.     else
  1845.         ap1 = gen_expr(ep, F_ALL, size);
  1846.  
  1847.     if (ap1->mode == am_freg) {
  1848.         gen_code(op_move, 4, makedreg((enum e_am) 1), push);
  1849.         gen_code(op_move, 4, makedreg((enum e_am) 0), push);
  1850.         size = 8;
  1851.     }
  1852.     else {
  1853.         if (size <= 4)
  1854.             gen_code(op_move, size, ap1, push);
  1855.         else {
  1856.             ap2 = copy_addr(ap1);
  1857.             ap2 = make_delta(ap2, 4);
  1858.             gen_code(op_move, 4, ap2, push);
  1859.             ap2 = copy_addr(ap1);
  1860.             gen_code(op_move, 4, ap2, push);
  1861.             size = 8;
  1862.         }
  1863.     }
  1864.     freeop(ap1);
  1865.  
  1866.     return size;
  1867. }
  1868.  
  1869. int
  1870. gen_parms(plist)
  1871.  
  1872. /*
  1873.  * push a list of parameters onto the stack and return the number of
  1874.  * parameters pushed.
  1875.  */
  1876.     struct enode   *plist;
  1877. {
  1878.     int             i, size;
  1879.     struct enode   *tplist;
  1880.  
  1881.     i = 0;
  1882.     if (plist != NULL) {
  1883.         tplist = plist->v.p[1];
  1884.         plist = plist->v.p[0];
  1885.     }
  1886.     while (plist != NULL) {
  1887.         size = getsize(plist->v.p[0]);
  1888.         i += push_param(plist->v.p[0], size);
  1889.         plist = plist->v.p[1];
  1890.         tplist = tplist->v.p[1];
  1891.     }
  1892.     return i;
  1893. }
  1894.  
  1895. struct amode   *
  1896. gen_fcall(node, flags)
  1897.  
  1898. /*
  1899.  * generate a function call node and return the address mode of the result.
  1900.  */
  1901.     struct enode   *node;
  1902.     int             flags;
  1903. {
  1904.     struct amode   *ap, *result;
  1905.     int             i;
  1906.  
  1907.     if (node == NULL) {
  1908.         fprintf( stderr, "DIAG -- null node in gen_fcall.\n" );
  1909.         return NULL;
  1910.     }
  1911.  
  1912.     flush_regs();       /* Push the used registers on the stack */
  1913.  
  1914.     i = gen_parms(node->v.p[1]);    /* generate parameters */
  1915.  
  1916.     if (!gen_builtins(node, i)) {
  1917.         if (!gen_libcall(node, i)) {
  1918.             if (node->v.p[0]->nodetype == en_nacon)
  1919.                 gen_code(op_jsr, 0, make_offset(node->v.p[0]), NULL);
  1920.             else {
  1921.                 ap = gen_expr(node->v.p[0], F_AREG, 4);
  1922.                 make_legal(ap, F_AREG, 4);
  1923.                 ap->mode = am_ind;
  1924.                 gen_code(op_jsr, 0, ap, NULL);
  1925.                 freeop(ap);
  1926.             }
  1927.             if (i != 0)
  1928.                 gen_code(op_add, 4, make_immed((long) i), makeareg(am_xpc));
  1929.         }
  1930.     }
  1931.  
  1932.     if (flags & F_FREG) {
  1933.         result = temp_float();
  1934.     }
  1935.     else {
  1936.         if (flags & F_DREG)
  1937.             result = temp_data();
  1938.         else
  1939.             result = temp_addr();
  1940.         if (result->preg != am_dreg || (flags & F_DREG) == 0)
  1941.             gen_code(op_move, 4, makedreg(am_dreg), result);
  1942.     }
  1943.     return result;
  1944. }
  1945.  
  1946. struct amode   *
  1947. gen_expr(node, flags, size)
  1948.  
  1949. /*
  1950.  * general expression evaluation. returns the addressing mode of the result.
  1951.  */
  1952.     struct enode   *node;
  1953.     int             flags, size;
  1954. {
  1955.     struct amode   *ap1, *ap2;
  1956.     struct enode   *ep;
  1957.     int             lab0, lab1;
  1958.     int             natsize;
  1959.  
  1960.     if (node == NULL)
  1961.         return NULL;
  1962.  
  1963.     switch (node->nodetype) {
  1964.     case en_stabn:
  1965.         return gen_stabn(node, flags, size);
  1966.         break;
  1967.     case en_stabs:
  1968.         return gen_stabs(node, flags, size);
  1969.         break;
  1970.     case en_fcon:
  1971.         ep = makenode(en_labcon, floatlit(node->v.f), NULL );
  1972.         ep = makenode(en_d_ref, ep, NULL );
  1973.         return(gen_expr(ep, flags, size));
  1974.     case en_labcon:
  1975.     case en_nacon:
  1976.     case en_icon:
  1977.         ap1 = (struct amode *) xalloc(sizeof(struct amode));
  1978.         ap1->signedflag = node->signedflag;
  1979.         ap1->mode = am_immed;
  1980.         ap1->offset = node;
  1981.         if (!(flags & F_IMMED))
  1982.             make_legal(ap1, flags, size);
  1983.         return (ap1);
  1984.     case en_autocon:
  1985.         ap2 = (struct amode *) xalloc(sizeof(struct amode));
  1986.         ap2->signedflag = node->signedflag;
  1987.         ap2->mode = am_immed;
  1988.         ap2->preg = (enum e_am) Options.Frame;  /* frame pointer */
  1989.         ap2->offset = node; /* use as constant node */
  1990.         if (!(flags & F_IMMED)) {
  1991.             natsize = natural_size(node);
  1992.             if (natsize > size)
  1993.                 size = natsize;
  1994.             make_legal(ap2, flags, size);
  1995.         }
  1996.         return (ap2);
  1997.     case en_b_ref:
  1998.     case en_ub_ref:
  1999.     case en_w_ref:
  2000.     case en_uw_ref:
  2001.     case en_l_ref:
  2002.     case en_ul_ref:
  2003.     case en_m_ref:
  2004.     case en_f_ref:
  2005.     case en_d_ref:
  2006.         return gen_deref(node, flags, size);
  2007.     case en_clf:
  2008.     case en_cld:
  2009.     case en_cfl:
  2010.     case en_cfd:
  2011.         return gen_fsconvert(node, flags, size);
  2012.     case en_cdf:
  2013.     case en_cdl:
  2014.         return gen_fconvert(node, flags, size);
  2015.     case en_cbl:
  2016.     case en_cwl:
  2017.         return gen_extend(node, flags, size);
  2018.     case en_tempref:
  2019.         ap1 = (struct amode *) xalloc(sizeof(struct amode));
  2020.         ap1->signedflag = node->signedflag;
  2021.         if (node->v.i < 8) {
  2022.             ap1->mode = am_dreg;
  2023.             ap1->preg = (enum e_am) (node->v.i);
  2024.             ap1->deep = 0;
  2025.         }
  2026.         else {
  2027.             ap1->mode = am_areg;
  2028.             ap1->preg = (enum e_am) (node->v.i - 8);
  2029.             ap1->deep = 0;
  2030.         }
  2031.         ap1->tempflag = 0;  /* not a temporary */
  2032.         make_legal(ap1, flags, size);
  2033.         return ap1;
  2034.     case en_fnegd:
  2035.         return gen_funary(node, flags, size, op_fneg);
  2036.     case en_fnegs:
  2037.         return gen_fsunary(node, flags, size, op_fneg);
  2038.     case en_uminus:
  2039.         return gen_unary(node, flags, size, op_neg);
  2040.     case en_compl:
  2041.         return gen_unary(node, flags, size, op_not);
  2042.     case en_faddd:
  2043.         return gen_fbinary(node, flags, size, op_fadd);
  2044.     case en_fadds:
  2045.         return gen_fsbinary(node, flags, size, op_fadd);
  2046.     case en_add:
  2047.         return gen_binary(node, flags, size, op_add);
  2048.     case en_fsubd:
  2049.         return gen_fbinary(node, flags, size, op_fsub);
  2050.     case en_fsubs:
  2051.         return gen_fsbinary(node, flags, size, op_fsub);
  2052.     case en_sub:
  2053.         return gen_binary(node, flags, size, op_sub);
  2054.     case en_and:
  2055.         return gen_binary(node, flags, size, op_and);
  2056.     case en_or:
  2057.         return gen_binary(node, flags, size, op_or);
  2058.     case en_xor:
  2059.         return gen_xbin(node, flags, size, op_eor);
  2060.     case en_fmuld:
  2061.         return gen_fbinary(node, flags, size, op_fmul);
  2062.     case en_fmuls:
  2063.         return gen_fsbinary(node, flags, size, op_fmul);
  2064.     case en_fdivd:
  2065.         return gen_fbinary(node, flags, size, op_fdiv);
  2066.     case en_fdivs:
  2067.         return gen_fsbinary(node, flags, size, op_fdiv);
  2068.     case en_fmodd:
  2069.         return gen_fbinary(node, flags, size, op_fmod);
  2070.     case en_fmods:
  2071.         return gen_fsbinary(node, flags, size, op_fmod);
  2072.     case en_faincs:
  2073.         return gen_fsaincdec(node, flags, size, op_fadd);
  2074.     case en_fadecs:
  2075.         return gen_fsaincdec(node, flags, size, op_fsub);
  2076.     case en_faincd:
  2077.         return gen_faincdec(node, flags, size, op_fadd);
  2078.     case en_fadecd:
  2079.         return gen_faincdec(node, flags, size, op_fsub);
  2080.     case en_mul:
  2081.         return gen_mul(node, flags, size, op_muls);
  2082.     case en_umul:
  2083.         return gen_mul(node, flags, size, op_mulu);
  2084.     case en_div:
  2085.         return gen_modiv(node, flags, size, op_divs);
  2086.     case en_udiv:
  2087.         return gen_modiv(node, flags, size, op_divu);
  2088.     case en_mod:
  2089.         return gen_modiv(node, flags, size, op_mods);
  2090.     case en_umod:
  2091.         return gen_modiv(node, flags, size, op_modu);
  2092.     case en_lsh:
  2093.         return gen_shift(node, flags, size, op_asl);
  2094.     case en_rsh:
  2095.         return gen_shift(node, flags, size, op_asr);
  2096.     case en_asadd:
  2097.         return gen_asadd(node, flags, size, op_add);
  2098.     case en_asuadd:
  2099.         return gen_asadd(node, flags, size, op_add);  /* TODO - broken */
  2100.     case en_assub:
  2101.         return gen_asadd(node, flags, size, op_sub);
  2102.     case en_asusub:
  2103.         return gen_asadd(node, flags, size, op_sub);  /* TODO - broken */
  2104.     case en_asand:
  2105.         return gen_aslogic(node, flags, size, op_and);
  2106.     case en_asor:
  2107.         return gen_aslogic(node, flags, size, op_or);
  2108.     case en_aseor:
  2109.         return gen_aslogic(node, flags, size, op_eor);
  2110.     case en_aslsh:
  2111.         return gen_asshift(node, flags, size, op_asl);
  2112.     case en_asrsh:
  2113.         return gen_asshift(node, flags, size, op_asr);
  2114.     case en_asmul:
  2115.         return gen_asmul(node, flags, size);
  2116.     case en_asumul:
  2117.         return gen_asmul(node, flags, size);
  2118.     case en_asdiv:
  2119.         return gen_asmodiv(node, flags, size, op_divs);
  2120.     case en_asudiv:
  2121.         return gen_asmodiv(node, flags, size, op_divu);
  2122.     case en_asmod:
  2123.         return gen_asmodiv(node, flags, size, op_mods);
  2124.     case en_asumod:
  2125.         return gen_asmodiv(node, flags, size, op_modu);
  2126.     case en_assign:
  2127.         return gen_assign(node, flags, size);
  2128.     case en_ainc:
  2129.         return gen_aincdec(node, flags, size, op_add);
  2130.     case en_adec:
  2131.         return gen_aincdec(node, flags, size, op_sub);
  2132.     case en_land:
  2133.     case en_lor:
  2134.     case en_not:
  2135.     case en_eq:
  2136.     case en_ne:
  2137.     case en_lt:
  2138.     case en_ult:
  2139.     case en_le:
  2140.     case en_ule:
  2141.     case en_gt:
  2142.     case en_ugt:
  2143.     case en_ge:
  2144.     case en_uge:
  2145.         lab0 = nextlabel++;
  2146.         lab1 = nextlabel++;
  2147.         falsejp(node, lab0);
  2148.         ap1 = temp_data();
  2149.         gen_code(op_moveq, 0, make_immed(1L), ap1);
  2150.         gen_code(op_bra, 0, make_label(lab1), NULL);
  2151.         gen_label(lab0);
  2152.         gen_code(op_clr, 4, ap1, NULL);
  2153.         gen_label(lab1);
  2154.         return ap1;
  2155.     case en_cond:
  2156.         return gen_hook(node, flags, size);
  2157.     case en_void:
  2158.         natsize = natural_size(node->v.p[0]);
  2159.         ap1 = gen_expr( node->v.p[0], F_ALL | F_NOVALUE, natsize);
  2160.         freeop( ap1 );
  2161.         ap2 = gen_expr( node->v.p[1], flags, size );
  2162.         return( ap2 );
  2163.     case en_fcall:
  2164.         return gen_fcall(node, flags);
  2165.     default:
  2166.         fprintf( stderr, "DIAG -- uncoded node in gen_expr.\n");
  2167.         return NULL;
  2168.     }
  2169.     return NULL;
  2170. }
  2171.  
  2172. int
  2173. natural_size(node)
  2174.  
  2175. /*
  2176.  * return the natural evaluation size of a node.
  2177.  */
  2178.     struct enode   *node;
  2179. {
  2180.     int             siz0, siz1;
  2181.     struct enode   *ep1;
  2182.  
  2183.     if (node == NULL)
  2184.         return 0;
  2185.     switch (node->nodetype) {
  2186.     case en_clf:
  2187.     case en_cdf:
  2188.     case en_f_ref:
  2189.     case en_fnegs:
  2190.     case en_fadds:
  2191.     case en_fsubs:
  2192.     case en_fmuls:
  2193.     case en_fdivs:
  2194.     case en_fmods:
  2195.     case en_faincs:
  2196.     case en_fadecs:
  2197.         return 4;
  2198.     case en_d_ref:
  2199.     case en_cld:
  2200.     case en_cfd:
  2201.     case en_fnegd:
  2202.     case en_faddd:
  2203.     case en_fsubd:
  2204.     case en_fmuld:
  2205.     case en_fdivd:
  2206.     case en_fmodd:
  2207.     case en_faincd:
  2208.     case en_fadecd:
  2209.         return 8;
  2210.     case en_m_ref:
  2211.         ep1 = node->v.p[1];
  2212.         return (ep1->v.i);
  2213.         break;
  2214.     case en_icon:
  2215.         if (-128 <= node->v.i && node->v.i <= 127)
  2216.             return 1;
  2217.         if (-32767 <= node->v.i && node->v.i <= 32767)
  2218.             return 2;
  2219.         return 4;
  2220.     case en_fcall:
  2221.     case en_labcon:
  2222.     case en_nacon:
  2223.     case en_autocon:
  2224.     case en_l_ref:
  2225.     case en_ul_ref:
  2226.     case en_tempref:
  2227.     case en_cbl:
  2228.     case en_cwl:
  2229.     case en_cdl:
  2230.     case en_cfl:
  2231.         return 4;
  2232.     case en_b_ref:
  2233.     case en_ub_ref:
  2234.         return 1;
  2235.     case en_cbw:
  2236.     case en_w_ref:
  2237.     case en_uw_ref:
  2238.         return 2;
  2239.     case en_not:
  2240.     case en_compl:
  2241.     case en_uminus:
  2242.     case en_assign:
  2243.     case en_ainc:
  2244.     case en_adec:
  2245.         return natural_size(node->v.p[0]);
  2246.     case en_add:
  2247.     case en_sub:
  2248.     case en_mul:
  2249.     case en_div:
  2250.     case en_mod:
  2251.     case en_uadd:
  2252.     case en_usub:
  2253.     case en_umul:
  2254.     case en_udiv:
  2255.     case en_umod:
  2256.     case en_and:
  2257.     case en_or:
  2258.     case en_xor:
  2259.     case en_lsh:
  2260.     case en_rsh:
  2261.     case en_eq:
  2262.     case en_ne:
  2263.     case en_lt:
  2264.     case en_ult:
  2265.     case en_le:
  2266.     case en_ule:
  2267.     case en_gt:
  2268.     case en_ugt:
  2269.     case en_ge:
  2270.     case en_uge:
  2271.     case en_land:
  2272.     case en_lor:
  2273.     case en_asadd:
  2274.     case en_assub:
  2275.     case en_asmul:
  2276.     case en_asdiv:
  2277.     case en_asmod:
  2278.     case en_asumul:
  2279.     case en_asudiv:
  2280.     case en_asumod:
  2281.     case en_asand:
  2282.     case en_asor:
  2283.     case en_aseor:
  2284.     case en_aslsh:
  2285.     case en_asrsh:
  2286.         siz0 = natural_size(node->v.p[0]);
  2287.         siz1 = natural_size(node->v.p[1]);
  2288.         if (siz1 > siz0)
  2289.             return siz1;
  2290.         else
  2291.             return siz0;
  2292.     case en_void:
  2293.     case en_cond:
  2294.         return natural_size(node->v.p[1]);
  2295.     default:
  2296.         fprintf( stderr, "DIAG -- natural size error.\n" );
  2297.         break;
  2298.     }
  2299.     return 0;
  2300. }
  2301.  
  2302. void
  2303. gen_compare(node)
  2304.  
  2305. /*
  2306.  * generate code to do a comparison of the two operands of node.
  2307.  */
  2308.     struct enode   *node;
  2309. {
  2310.     struct amode   *ap1, *ap2;
  2311.     int             size, flags;
  2312.  
  2313.     if (node->v.p[0]->nodetype == en_cbl) {
  2314.         if (node->v.p[1]->nodetype == en_cbl) {
  2315.             node->v.p[0] = node->v.p[0]->v.p[0];
  2316.             node->v.p[1] = node->v.p[1]->v.p[0];
  2317.         }
  2318.         else if (isbyte(node->v.p[1])) {
  2319.             node->v.p[0] = node->v.p[0]->v.p[0];
  2320.         }
  2321.     }
  2322.  
  2323.     if (node->v.p[1]->nodetype == en_cbl) {
  2324.         if (isbyte(node->v.p[0])) {
  2325.             node->v.p[1] = node->v.p[1]->v.p[0];
  2326.         }
  2327.     }
  2328.  
  2329.     if (node->v.p[0]->nodetype == en_cwl) {
  2330.         if (node->v.p[1]->nodetype == en_cwl) {
  2331.             node->v.p[0] = node->v.p[0]->v.p[0];
  2332.             node->v.p[1] = node->v.p[1]->v.p[0];
  2333.         }
  2334.         else if (isshort(node->v.p[1])) {
  2335.             node->v.p[0] = node->v.p[0]->v.p[0];
  2336.         }
  2337.     }
  2338.  
  2339.     if (node->v.p[1]->nodetype == en_cwl) {
  2340.         if (isshort(node->v.p[0])) {
  2341.             node->v.p[1] = node->v.p[1]->v.p[0];
  2342.         }
  2343.     }
  2344.  
  2345.     size = natural_size(node);
  2346.  
  2347.     if (size <= 4) {
  2348.         flags = F_AREG | F_DREG | F_IMMED | F_MEM;
  2349.         ap1 = gen_expr(node->v.p[0], F_DREG, size);
  2350.         make_legal(ap1, F_DREG, size);
  2351.         ap2 = gen_expr(node->v.p[1], flags, size);
  2352.         make_legal(ap2, flags, size);
  2353.         validate(ap1);
  2354.         gen_code(op_cmp, size, ap1, ap2);
  2355.         freeop(ap2);
  2356.         freeop(ap1);
  2357.     }
  2358.     else {
  2359.         ap1 = gen_fbinary(node, F_FREG, size, op_cmp);
  2360.         freeop(ap1);
  2361.         gen_code(op_cmp, 4, make_immed((long) 0), makedreg((enum e_am) 0));
  2362.     }
  2363. }
  2364.  
  2365. void
  2366. truejp(node, label)
  2367.  
  2368. /*
  2369.  * generate a jump to label if the node passed evaluates to a true condition.
  2370.  */
  2371.     struct enode   *node;
  2372.     int             label;
  2373. {
  2374.     struct amode   *ap1;
  2375.     int             siz1;
  2376.     int             lab0;
  2377.  
  2378.     if (node == NULL)
  2379.         return;
  2380.     switch (node->nodetype) {
  2381.     case en_eq:
  2382.         gen_compare(node);
  2383.         gen_code(op_beq, 0, make_label(label), NULL);
  2384.         break;
  2385.     case en_ne:
  2386.         gen_compare(node);
  2387.         gen_code(op_bne, 0, make_label(label), NULL);
  2388.         break;
  2389.     case en_lt:
  2390.         gen_compare(node);
  2391.         gen_code(op_blt, 0, make_label(label), NULL);
  2392.         break;
  2393.     case en_le:
  2394.         gen_compare(node);
  2395.         gen_code(op_ble, 0, make_label(label), NULL);
  2396.         break;
  2397.     case en_gt:
  2398.         gen_compare(node);
  2399.         gen_code(op_bgt, 0, make_label(label), NULL);
  2400.         break;
  2401.     case en_ge:
  2402.         gen_compare(node);
  2403.         gen_code(op_bge, 0, make_label(label), NULL);
  2404.         break;
  2405.     case en_ult:
  2406.         gen_compare(node);
  2407.         gen_code(op_bcs, 0, make_label(label), NULL);
  2408.         break;
  2409.     case en_ule:
  2410.         gen_compare(node);
  2411.         gen_code(op_bls, 0, make_label(label), NULL);
  2412.         break;
  2413.     case en_ugt:
  2414.         gen_compare(node);
  2415.         gen_code(op_bhi, 0, make_label(label), NULL);
  2416.         break;
  2417.     case en_uge:
  2418.         gen_compare(node);
  2419.         gen_code(op_bcc, 0, make_label(label), NULL);
  2420.         break;
  2421.     case en_land:
  2422.         lab0 = nextlabel++;
  2423.         falsejp(node->v.p[0], lab0);
  2424.         truejp(node->v.p[1], label);
  2425.         gen_label(lab0);
  2426.         break;
  2427.     case en_lor:
  2428.         truejp(node->v.p[0], label);
  2429.         truejp(node->v.p[1], label);
  2430.         break;
  2431.     case en_not:
  2432.         falsejp(node->v.p[0], label);
  2433.         break;
  2434.     default:
  2435.         siz1 = natural_size(node);
  2436.         ap1 = gen_expr(node, F_DREG, siz1);
  2437.         make_legal(ap1, F_DREG, siz1);
  2438.         gen_code(op_tst, siz1, ap1, NULL);
  2439.         freeop(ap1);
  2440.         gen_code(op_bne, 0, make_label(label), NULL);
  2441.         break;
  2442.     }
  2443. }
  2444.  
  2445. void
  2446. falsejp(node, label)
  2447.  
  2448. /*
  2449.  * generate code to execute a jump to label if the expression passed is
  2450.  * false.
  2451.  */
  2452.     struct enode   *node;
  2453.     int             label;
  2454. {
  2455.     struct amode   *ap;
  2456.     int             siz1;
  2457.     int             lab0;
  2458.  
  2459.     if (node == NULL)
  2460.         return;
  2461.     switch (node->nodetype) {
  2462.     case en_eq:
  2463.         gen_compare(node);
  2464.         gen_code(op_bne, 0, make_label(label), NULL);
  2465.         break;
  2466.     case en_ne:
  2467.         gen_compare(node);
  2468.         gen_code(op_beq, 0, make_label(label), NULL);
  2469.         break;
  2470.     case en_lt:
  2471.         gen_compare(node);
  2472.         gen_code(op_bge, 0, make_label(label), NULL);
  2473.         break;
  2474.     case en_le:
  2475.         gen_compare(node);
  2476.         gen_code(op_bgt, 0, make_label(label), NULL);
  2477.         break;
  2478.     case en_gt:
  2479.         gen_compare(node);
  2480.         gen_code(op_ble, 0, make_label(label), NULL);
  2481.         break;
  2482.     case en_ge:
  2483.         gen_compare(node);
  2484.         gen_code(op_blt, 0, make_label(label), NULL);
  2485.         break;
  2486.     case en_ult:
  2487.         gen_compare(node);
  2488.         gen_code(op_bcc, 0, make_label(label), NULL);
  2489.         break;
  2490.     case en_ule:
  2491.         gen_compare(node);
  2492.         gen_code(op_bhi, 0, make_label(label), NULL);
  2493.         break;
  2494.     case en_ugt:
  2495.         gen_compare(node);
  2496.         gen_code(op_bls, 0, make_label(label), NULL);
  2497.         break;
  2498.     case en_uge:
  2499.         gen_compare(node);
  2500.         gen_code(op_bcs, 0, make_label(label), NULL);
  2501.         break;
  2502.     case en_land:
  2503.         falsejp(node->v.p[0], label);
  2504.         falsejp(node->v.p[1], label);
  2505.         break;
  2506.     case en_lor:
  2507.         lab0 = nextlabel++;
  2508.         truejp(node->v.p[0], lab0);
  2509.         falsejp(node->v.p[1], label);
  2510.         gen_label(lab0);
  2511.         break;
  2512.     case en_not:
  2513.         truejp(node->v.p[0], label);
  2514.         break;
  2515.     default:
  2516.         siz1 = natural_size(node);
  2517.         ap = gen_expr(node, F_DREG, siz1);
  2518.         make_legal(ap, F_DREG, siz1);
  2519.         gen_code(op_tst, siz1, ap, NULL);
  2520.         freeop(ap);
  2521.         gen_code(op_beq, 0, make_label(label), NULL);
  2522.         break;
  2523.     }
  2524. }
  2525.